package de.bk.timecalc.midlet.statemachine;

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;

import de.bk.timecalc.core.ChallengeDTO;
import de.bk.timecalc.core.LineNotParseableException;
import de.bk.timecalc.core.LineParser;
import de.bk.timecalc.core.TimeCalcCore;
import de.bk.timecalc.core.TimeDTO;
import de.bk.timecalc.midlet.Commands;

public class GuiStateGame extends AbstractGuiState
{
  private TimeCalcCore timeCalcCore;
  private LineParser lineParser;

  private Form form;
  private TextField textFieldChallenge;
  private StringItem textFeedbackRightWrong;
  private StringItem textStatisticsTimeForLastAnswer;
  private StringItem textStatisticsScoreForLastAnswer;
  private StringItem textStatisticsScoreTotal;
  private StringItem textStatisticsScoreAverage;

  GuiStateGame(StateMachine stateMachine)
  {
    super(stateMachine);
  }

  void init()
  {
    this.initCore();
    this.createForm();
  }

  private void initCore()
  {
    this.timeCalcCore = new TimeCalcCore();
    this.lineParser = new LineParser();
  }

  void enter()
  {
    this.timeCalcCore.reset();
    this.resetForm();
    this.getDisplay().setCurrent(this.form);
    this.showNewChallenge();
  }

  void leave()
  {
    this.timeCalcCore.cancelChallenge();
  }

  void destroy()
  {
    this.timeCalcCore = null;
    this.lineParser = null;

    this.form = null;
    this.textFieldChallenge = null;
    this.textFeedbackRightWrong = null;
  }

  private void createForm()
  {
    this.form = new Form("QL Time Calc Trainer");
    CommandListenerGame commandListener = new CommandListenerGame(this);
    this.form.setCommandListener(commandListener);
    this.form.addCommand(Commands.exit);

    // text field with label for challenge
    this.textFieldChallenge = new TextField("", "", 4, TextField.NUMERIC);
    this.textFieldChallenge.addCommand(Commands.challengeOk);
    this.textFieldChallenge.setItemCommandListener(commandListener);
    this.form.append(this.textFieldChallenge);

    // feedback
    this.textFeedbackRightWrong = new StringItem("", "", Item.PLAIN);
    this.form.append(this.textFeedbackRightWrong);

    // score
    this.textStatisticsTimeForLastAnswer = new StringItem("Time:", "",
        Item.PLAIN);
    this.form.append(this.textStatisticsTimeForLastAnswer);
    this.textStatisticsScoreForLastAnswer = new StringItem("Last:", "",
        Item.PLAIN);
    this.form.append(this.textStatisticsScoreForLastAnswer);
    this.textStatisticsScoreTotal = new StringItem("Total:", "", Item.PLAIN);
    this.form.append(this.textStatisticsScoreTotal);
    this.textStatisticsScoreAverage = new StringItem("Average:", "", Item.PLAIN);
    this.form.append(this.textStatisticsScoreAverage);
  }

  private void resetForm()
  {
    this.textFieldChallenge.setString("");
    this.textFeedbackRightWrong.setText("");
    this.textStatisticsTimeForLastAnswer.setText("");
    this.textStatisticsScoreForLastAnswer.setText("");
    this.textStatisticsScoreTotal.setText("");
    this.textStatisticsScoreAverage.setText("");

  }

  private void showNewChallenge()
  {
    ChallengeDTO challenge = this.timeCalcCore.nextChallenge();
    StringBuffer challengeAsString = new StringBuffer();
    challengeAsString.append(challenge.getTime().toString());
    if (this.timeCalcCore.isTimerCountsDown())
    {
      challengeAsString.append(" - ");
    }
    else
    {
      challengeAsString.append(" + ");
    }
    challengeAsString.append(challenge.getDifference().getDisplayText());
    this.textFieldChallenge.setLabel(challengeAsString.toString());
    this.textFieldChallenge.setString("");
  }

  void checkAnswer(String answer)
  {
    try
    {
      TimeDTO time = this.lineParser.parse(answer);
      boolean correct = this.timeCalcCore.checkAnswerForLastChallenge(time);
      if (correct)
      {
        this.textFeedbackRightWrong.setText("Right");
      }
      else
      {
        this.textFeedbackRightWrong.setText("Wrong - "
            + this.timeCalcCore.getAnswerForLastChallenge().toString());
      }

      this.textStatisticsTimeForLastAnswer.setText(this.timeCalcCore
          .getTimeNeededForLastAnswer().toString());
      this.textStatisticsScoreForLastAnswer.setText(this
          .float2String(this.timeCalcCore.getScoreForLastAnswer()));
      this.textStatisticsScoreTotal.setText(this.float2String(this.timeCalcCore
          .getScore()));
      this.textStatisticsScoreAverage.setText(this
          .float2String(this.timeCalcCore.getScore()
              / (float) this.timeCalcCore.getChallengesDone()));

      this.showNewChallenge();
    }
    catch (LineNotParseableException e)
    {
      Alert alert = new Alert("Time could not be parsed");
      alert.setString(e.getMessage());
      this.textFieldChallenge.setString("");
      this.getDisplay().setCurrent(alert);
    }
  }

  boolean isTimerCountsDown()
  {
    return this.timeCalcCore.isTimerCountsDown();
  }

  void setTimerCountsDown(boolean timerCountsDown)
  {
    this.timeCalcCore.setTimerCountsDown(timerCountsDown);
  }

  private String float2String(float f)
  {
    return Float.toString(f);
  }

}
